package com.m3958.firstgwt.client.ui;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import com.google.gwt.cell.client.ActionCell;
import com.google.gwt.cell.client.ActionCell.Delegate;
import com.google.gwt.cell.client.CheckboxCell;
import com.google.gwt.cell.client.ClickableTextCell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.cell.client.ImageCell;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.SimplePager;
import com.google.gwt.user.cellview.client.SimplePager.TextLocation;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.DefaultSelectionEventManager;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.Range;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SingleSelectionModel;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.m3958.firstgwt.client.AppStatus;
import com.m3958.firstgwt.client.datasource.AssetAsyncDataProvider;
import com.m3958.firstgwt.client.datasource.AssetDataSource;
import com.m3958.firstgwt.client.event.SiteChangeEvent;
import com.m3958.firstgwt.client.event.SiteChangeEventHandler;
import com.m3958.firstgwt.client.rpc.MyRpcCallback;
import com.m3958.firstgwt.client.service.AppUiService;
import com.m3958.firstgwt.client.service.AppUtilService;
import com.m3958.firstgwt.client.service.VblockService;
import com.m3958.firstgwt.client.types.SmartOperationName;
import com.m3958.firstgwt.shared.type.SmartConstants;
import com.m3958.firstgwt.shared.type.SmartParameterName;
import com.m3958.gwtutil.clientside.client.HtmlFileUploader;
import com.m3958.gwtutil.clientside.client.HtmlFileUploaderFactory;
import com.m3958.gwtutil.clientside.client.YuiWrapper;
import com.m3958.gwtutil.clientside.client.interfac.IWaitingFileUploadResult;
import com.m3958.gwtutil.clientside.client.jso.AssetJso;
import com.m3958.gwtutil.clientside.client.jso.UploadResponseJso;
import com.smartgwt.client.rpc.RPCManager;
import com.smartgwt.client.rpc.RPCRequest;
import com.smartgwt.client.rpc.RPCResponse;
import com.smartgwt.client.util.BooleanCallback;
import com.smartgwt.client.util.SC;



@Singleton
public class AttachmentsManager extends Composite implements IWaitingFileUploadResult{

	private static AttachmentsManagerUiBinder uiBinder = GWT
			.create(AttachmentsManagerUiBinder.class);
	
	Logger logger = Logger.getLogger(this.getClass().getName());
	
	@UiField(provided=true)
	HtmlFileUploader htmlFileUploader;
	
	@UiField
	HTMLPanel myContainer;
	
	@Inject
	private AppUiService auiService;
	
	@UiField
	DivElement aatContainer;
	
	@UiField
	Anchor aviewSwitchAnchor;
	
	@UiField
	DivElement myatContainer;
	

	@Inject
	private AppUiService aui;
	
	@UiField
	ListBox sizeSelector;
	
	@UiField
	Button insertImgBt;
	
	@UiField
	Button insertLinkBt;
	
	@UiField
	Button deleteAtBt;

	
	@Inject
	private YuiWrapper yui;
	
	@Inject
	private VblockService bservice;
	
	
	@Inject
	private AppStatus aservice;
	
	private SingleSelectionModel<AssetJso> aatSelectionModel;
	
	private SingleSelectionModel<AssetJso> myatSelectionModel;
	
	@UiField(provided = true)
	CellTable<AssetJso> aatCellTable;
	
	@UiField(provided = true)
	SimplePager aatPager;
	
	@UiField(provided = true)
	CellTable<AssetJso> myatCellTable;
	
	@UiField(provided = true)
	SimplePager myatPager;
	
	@Inject
	private EventBus eventBus;
	
	@Inject
	private HtmlFileUploaderFactory uploaderFacotry;

	private boolean inMyat = false;
	
	private boolean uploading = false;
	
	private ListDataProvider<AssetJso> dataProvider = new ListDataProvider<AssetJso>();
	
	@Inject
	private AssetAsyncDataProvider asyncDp;

	interface AttachmentsManagerUiBinder extends
			UiBinder<Widget, AttachmentsManager> {
	}
	
	private boolean initialized = false;
	
	private boolean myAtNeedRefresh = false;
	
	public AttachmentsManager initMe(){
		if(!initialized){
			initialized = true;
			yui.logString("c1");
			initAatCellTable();
			yui.logString("c2");
			initMyatCellTable();
			yui.logString("c3");
			htmlFileUploader = uploaderFacotry.getArticleEditHtmlFileUploader(bservice.getSiteId(), this);
			yui.logString("c4");
			initWidget(uiBinder.createAndBindUi(this));
			yui.logString("c5");
			myatContainer.getStyle().setDisplay(Display.NONE);
			yui.logString("c6");
			setImgSizeSelector();
			yui.logString("c7");
			eventBus.addHandler(SiteChangeEvent.TYPE,new SiteChangeEventHandler() {
				@Override
				public void onSiteChange(SiteChangeEvent event) {
					myAtNeedRefresh = true;
					htmlFileUploader.setSiteId(event.getSiteId());
				}
			});
		}
		yui.logString("c8");
		return this;
	}
	

	private void changeBtnStatus() {
		if(inMyat){
			if(myatSelectionModel.getSelectedObject() != null){
				enableBtns(true);
				return;
			}
		}else{
			if(aatSelectionModel.getSelectedObject() != null){
				enableBtns(true);
				return;
			}
		}
		enableBtns(false);
	}
	
	private void enableBtns(boolean tf){
		insertImgBt.setEnabled(tf);
		insertLinkBt.setEnabled(tf);
		deleteAtBt.setEnabled(tf);
	}
	
	private void initMyatCellTable(){
		myatCellTable = new CellTable<AssetJso>(15);
		myatCellTable.setWidth("100%", true);
	    SimplePager.Resources pagerResources = GWT.create(SimplePager.Resources.class);
	    myatPager = new SimplePager(TextLocation.CENTER, pagerResources, false, 0, true);
	    myatPager.setDisplay(myatCellTable);
	    myatPager.setPageSize(5);
	    myatSelectionModel = new SingleSelectionModel<AssetJso>();
	    myatSelectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
			@Override
			public void onSelectionChange(SelectionChangeEvent event) {
					changeBtnStatus();
			}
		});
		
		myatCellTable.setSelectionModel(myatSelectionModel,DefaultSelectionEventManager.<AssetJso>createCheckboxManager(0));
		
		
		Column<AssetJso,Boolean> selectCol = new Column<AssetJso, Boolean>(new CheckboxCell(false, true)) {
			@Override
			public Boolean getValue(AssetJso object) {
				return myatSelectionModel.isSelected(object);
			}
		};
		myatCellTable.addColumn(selectCol,"选定");
		
		selectCol.setFieldUpdater(new FieldUpdater<AssetJso, Boolean>() {
			@Override
			public void update(int index, AssetJso object, Boolean value) {
				myatSelectionModel.setSelected(object, value);
			}
		});
	
	    Column<AssetJso, String> originNameColumn = new Column<AssetJso, String>(new ClickableTextCell()) {
	      @Override
	      public String getValue(AssetJso object) {
	        return object.getOriginName();
	      }
	    };
	    originNameColumn.setSortable(false);
	    myatCellTable.addColumn(originNameColumn,"文件名");
	    
	    Column<AssetJso, String> thumbColumn = new Column<AssetJso, String>(new ImageCell()) {
		      @Override
		      public String getValue(AssetJso object) {
		    	  if(object.isImg()){
		    		  return "/asset/" + object.getId() + ".48x48" + object.getExtension();
		    	  }else{
		    		  return null;
		    	  }
		      }
		    };
	    myatCellTable.addColumn(thumbColumn,"缩略图");
	    
	    ActionCell<AssetJso> ac = new ActionCell<AssetJso>("关联", new Delegate<AssetJso>() {
			@Override
			public void execute(AssetJso object) {
				for(AssetJso aj : dataProvider.getList()){
					if(aj.getId() == object.getId()){
						SC.warn("已经关联了！");
						return;
					}
				}
				switchToMyAtCellTable(false);
				object.setAttachment(true);
				dataProvider.getList().add(object);
				dataProvider.refresh();
			}
		});
	    
	    Column<AssetJso, String> fileSizeColumn = new Column<AssetJso, String>(new TextCell()) {
		      @Override
		      public String getValue(AssetJso object) {
		        return AppUtilService.SizeFormator.format(object.getFileSize());
		      }
		    };
		    myatCellTable.addColumn(fileSizeColumn,"大小");
	    
	    Column<AssetJso,AssetJso> attoArticleColumn = new Column<AssetJso,AssetJso>(ac) {
			@Override
			public AssetJso getValue(AssetJso object) {
				return object;
			}
		};
	    
	    myatCellTable.addColumn(attoArticleColumn,"关联到文章");
	    
	    myatCellTable.setColumnWidth(selectCol, 110,Unit.PX);
	    myatCellTable.setColumnWidth(originNameColumn, "100%");
	    myatCellTable.setColumnWidth(thumbColumn, 105, Unit.PX);
	    myatCellTable.setColumnWidth(fileSizeColumn, 105, Unit.PX);
	    myatCellTable.setColumnWidth(attoArticleColumn, 105, Unit.PX);
	    asyncDp.addDataDisplay(myatCellTable);
	}
	
	
	private void initAatCellTable(){
		aatCellTable = new CellTable<AssetJso>(15);
		aatCellTable.setWidth("100%", true);
	    SimplePager.Resources pagerResources = GWT.create(SimplePager.Resources.class);
	    aatPager = new SimplePager(TextLocation.CENTER, pagerResources, false, 0, true);
	    aatPager.setDisplay(aatCellTable);
	    aatPager.setPageSize(5);
	    aatSelectionModel = new SingleSelectionModel<AssetJso>();
	    aatSelectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
			@Override
			public void onSelectionChange(SelectionChangeEvent event) {
				changeBtnStatus();
			}
		});
		aatCellTable.setSelectionModel(aatSelectionModel,DefaultSelectionEventManager.<AssetJso>createCheckboxManager(0));
		
		
		Column<AssetJso,Boolean> selectCol = new Column<AssetJso, Boolean>(new CheckboxCell(false, true)) {
			@Override
			public Boolean getValue(AssetJso object) {
				return aatSelectionModel.isSelected(object);
			}
		};
		aatCellTable.addColumn(selectCol,"选定");
		
		selectCol.setFieldUpdater(new FieldUpdater<AssetJso, Boolean>() {
			@Override
			public void update(int index, AssetJso object, Boolean value) {
				aatSelectionModel.setSelected(object, value);
			}
		});
	
	    Column<AssetJso, String> originNameColumn = new Column<AssetJso, String>(new ClickableTextCell()) {
	      @Override
	      public String getValue(AssetJso object) {
	        return object.getOriginName();
	      }
	    };
	    originNameColumn.setSortable(true);
	    aatCellTable.addColumn(originNameColumn,"文件名");
	    
	    Column<AssetJso, String> thumbColumn = new Column<AssetJso, String>(new ImageCell()) {
		      @Override
		      public String getValue(AssetJso object) {
		    	  if(object.isImg()){
		    		  return "/asset/" + object.getId() + ".48x48" + object.getExtension();
		    	  }else{
		    		  return null;
		    	  }
		      }
		    };
	    aatCellTable.addColumn(thumbColumn,"缩略图");
	    
	    
	    Column<AssetJso, String> fileSizeColumn = new Column<AssetJso, String>(new TextCell()) {
		      @Override
		      public String getValue(AssetJso object) {
		        return AppUtilService.SizeFormator.format(object.getFileSize());
		      }
		    };
	    aatCellTable.addColumn(fileSizeColumn,"大小");

	    
	    Column<AssetJso, Boolean> titleImgColumn = new Column<AssetJso, Boolean>(new CheckboxCell(false, false)) {
			@Override
			public Boolean getValue(AssetJso object) {
				return object.isTitleImg();
			}
		};
		titleImgColumn.setFieldUpdater(new MyBooleanFieldUpdater("titleImg"));
		aatCellTable.addColumn(titleImgColumn,"标题图");
		
	    Column<AssetJso, Boolean> contentImgColumn = new Column<AssetJso, Boolean>(new CheckboxCell(false, false)) {
			@Override
			public Boolean getValue(AssetJso object) {
				return object.isContentImg();
			}
		};
		contentImgColumn.setFieldUpdater(new MyBooleanFieldUpdater("contentImg"));
		aatCellTable.addColumn(contentImgColumn,"内容图");

	    Column<AssetJso, Boolean> attachmentsColumn = new Column<AssetJso, Boolean>(new CheckboxCell(false, false)) {
			@Override
			public Boolean getValue(AssetJso object) {
				return object.isAttachment();
			}
		};
		attachmentsColumn.setFieldUpdater(new MyBooleanFieldUpdater("attachment"));
		aatCellTable.addColumn(attachmentsColumn,"附件");

	    
	    aatCellTable.setColumnWidth(selectCol, 110,Unit.PX);
	    aatCellTable.setColumnWidth(originNameColumn, "100%");
	    aatCellTable.setColumnWidth(thumbColumn, 105, Unit.PX);
	    aatCellTable.setColumnWidth(fileSizeColumn, 105, Unit.PX);
	    aatCellTable.setColumnWidth(titleImgColumn, 110,Unit.PX);
	    aatCellTable.setColumnWidth(contentImgColumn, 110,Unit.PX);
	    aatCellTable.setColumnWidth(attachmentsColumn, 110,Unit.PX);
	    
	    dataProvider.addDataDisplay(aatCellTable);
	}
	
		public void setAttach(JsArray<AssetJso> attas){
			yui.logJso(attas);
			if(attas == null){
				dataProvider.setList(new ArrayList<AssetJso>());
			}else{
				dataProvider.setList(convertToList(attas));
			}
			dataProvider.refresh();
		}
		
		private void setImgSizeSelector(){
			sizeSelector.clear();
			sizeSelector.addItem("");
			for(String s:getImgSizes()){
				sizeSelector.addItem(s);
			}
		}
		
		private String[] getImgSizes(){
			yui.logJso(aservice.getWebSite());//这个是null，问题所在！
			if(aservice.getWebSite() == null)return new String[]{};
			String s = aservice.getWebSite().getImgSizes();
			
			if(s == null || s.isEmpty())return new String[]{};
			return s.split(",");
		}
		
		public String getAttachStr(){
			return new JSONObject(getAttachStrNative(convertToJsArray(dataProvider.getList()))).toString();
		}
		
		public final native JavaScriptObject getAttachStrNative(JsArray<AssetJso> ajs)/*-{
			$wnd.Y.log(ajs);
			var jo = {contentImgs:[],attachments:[]};
			for(var i=0;i<ajs.length;i++){
				var ca = ajs[i];
				if(ca.isTitleImg){jo.titleImg = ca;}
				if(ca.isContentImg){jo.contentImgs.push(ca);}
				if(ca.isAttachment){jo.attachments.push(ca);}
			}
			$wnd.Y.log(jo);
			return jo;
		}-*/;
	  
		private List<AssetJso> convertToList(JsArray<AssetJso> ajs){
			List<AssetJso> assets = new ArrayList<AssetJso>();
			for(int i=0;i<ajs.length();i++){
				assets.add(ajs.get(i));
			}
			return assets;
		}

		private JsArray<AssetJso> convertToJsArray(List<AssetJso> ajs){
			JsArray<AssetJso> jsa = JsArray.createArray().cast();
			for(AssetJso aj:ajs){
				jsa.push(aj);
			}
			return jsa;
		}
		
		public class MyBooleanFieldUpdater implements FieldUpdater<AssetJso, Boolean>{
			private String filedName;
			
			public MyBooleanFieldUpdater(String fieldName){
				this.filedName = fieldName;
			}
			@Override
			public void update(int index, AssetJso object, Boolean value) {
				yui.logJso(object);
				if("titleImg".equals(filedName)){
					if(object.isImg()){
						for(AssetJso aj :dataProvider.getList()){
							aj.setTitleImg(false);
						}
						object.setTitleImg(value);
					}else{
						if(value){
							SC.warn("不是图片！");
						}
					}
				}else if("contentImg".equals(filedName)){
					yui.logJso(object);
					if(object.isImg()){
						object.setContentImg(value);
					}else{
						if(value){
							SC.warn("不是图片！");
						}
					}
				}else if("attachment".equals(filedName)){
					yui.logJso(object);
					object.setAttachment(value);
				}
				yui.logBoolean(dataProvider.getList().get(index).isTitleImg());
				if(!object.isAttachment() && !object.isContentImg() && !object.isTitleImg()){
					dataProvider.getList().remove(object);
				}
				dataProvider.refresh();
			}
			
		}
		
		@UiHandler("deleteAtBt")
		void handleAtBtClick(ClickEvent ce){
			if(getSelectedAsset(true) == null){
				return;
			}
			SC.confirm("确认删除？", new BooleanCallback() {
				@Override
				public void execute(Boolean value) {
					if(value){
						Map<String, String> m = new HashMap<String, String>();
				    	m.put(SmartParameterName.MODEL_NAME, AssetDataSource.className);
				    	m.put(SmartParameterName.OPERATION_TYPE, SmartOperationName.REMOVE.getValue());
				    	m.put(SmartParameterName.MODEL_ID, getSelectedAsset(true).getId()+"");
				    	RPCRequest rr = new RPCRequest();
				    	rr.setHttpMethod("POST");
				    	rr.setActionURL(SmartConstants.SMART_CRUD_URL);
				    	rr.setParams(m);
				    	RPCManager.sendRequest(rr,new MyRpcCallback(){
							@Override
							public void afterSuccess(RPCResponse response, JSONObject responseJo, RPCRequest request, JSONValue data) {
								JsArray<AssetJso> aj = data.isArray().getJavaScriptObject().cast();
								if(aj.length() == 1){
									afterDeleteAsset(aj.get(0));
								}else{
									SC.warn("删除失败！");
								}
							}});
					}
				}
			});
		}
		
		private void afterDeleteAsset(AssetJso asset){
			int id = asset.getId();
			auiService.showTmpPrompt("已删除！");
			AssetJso deletedAsset = null;
			if(inMyat){
				yui.logInt(myatPager.getPageStart());
				myatCellTable.setVisibleRangeAndClearData(new Range(myatPager.getPageStart(),myatPager.getPageSize()), true);
				deletedAsset = myatSelectionModel.getSelectedObject();
			}else{
				for(AssetJso a : dataProvider.getList()){
					if(a.getId() == id){
						dataProvider.getList().remove(a);
						break;
					}
				}
				dataProvider.refresh();
				aatCellTable.redraw();
				deletedAsset = aatSelectionModel.getSelectedObject();
			}
			if(deletedAsset != null){
				myatSelectionModel.setSelected(deletedAsset, false);
				enableBtns(false);
			}
		}
		
		@UiHandler("aviewSwitchAnchor")
		void handAviewSwitch(ClickEvent ce){
			ce.preventDefault();
			if(inMyat){
				switchToMyAtCellTable(false);
			}else{
				switchToMyAtCellTable(true);
			}
		}
		
		public void switchToMyAtCellTable(boolean switchToMyAt){
			if(switchToMyAt){
				inMyat = true;
				aatContainer.getStyle().setDisplay(Display.NONE);
				myatContainer.getStyle().clearDisplay();
				aviewSwitchAnchor.setText("切换到本文章的附件管理-》");
			}else{
				inMyat = false;
				myatContainer.getStyle().setDisplay(Display.NONE);
				aatContainer.getStyle().clearDisplay();
				aviewSwitchAnchor.setText("切换到全部附件管理-》");
			}
			changeBtnStatus();

		}
		
		@UiHandler("insertImgBt")
		void handleInsertImgBtClick(ClickEvent ce){
			insert2ke(getAttachmentsHtml(getSelectedAsset(true),"img",sizeSelector.getValue(sizeSelector.getSelectedIndex())));
		}
		
		@UiHandler("insertLinkBt")
		void handleInsertLinkBtClick(ClickEvent ce){
			insert2ke(getAttachmentsHtml(getSelectedAsset(true),"link",""));
		}
		
		public AssetJso getSelectedAsset(boolean warn){
			AssetJso aj = null;
			if(inMyat){
				aj = myatSelectionModel.getSelectedObject();
			}else{
				aj = aatSelectionModel.getSelectedObject();
			}
			if(aj == null && warn){
				SC.warn("请先选定一个对象！");
			}
			return aj;
		}
		
		 public final native void insert2ke(String html)/*-{
		 	var editorId = @com.m3958.firstgwt.client.layout.ArticleEditLayout::richEditorDomId;
		 	$wnd.Y.log(editorId); 
		 	$wnd.m3958editors[editorId].insertHtml(html);
		 }-*/;
		 

		 public final native String getAttachmentsHtml(AssetJso asset,String type,String size)/*-{
		 	if(!asset)return;
		 	var finaltpl;
		 	var isimg = false;
		 	if('img' == type){
		 		finaltpl = '<img src="{aurlsize}" alt="{originName}" style="border: 0;"/>';
		 		isimg = true;
		 	}else if('imglink' == type){
		 		finaltpl = '<a href="{aurl}" alt="{originName}"><img src="{aurlsize}" alt="{originName}" style="border: 0;"/></a>';
		 		isimg = true;
		 	}else{
		 		finaltpl = '<a href="{aurl}" title="{originName}">{originName}</a>';
		 	}
 	
		 	$wnd.Y.log(finaltpl);
	 		var o = {aurl:asset.url,originName:asset.originName};
	 		var j = o.aurl.lastIndexOf('.');
	 		if(size){
	 			var aurlsize = o.aurl.substring(0,j) + "." +  size + o.aurl.substring(j);
	 			o.aurlsize = aurlsize;
	 		}else{
	 			o.aurlsize = o.aurl;
	 		}
	 		$wnd.Y.log(o);
	 		return $wnd.Y.Lang.sub(finaltpl,o);
		 }-*/;
		 
		public void resetMyatCellTable() {
			if(myAtNeedRefresh){
				myAtNeedRefresh = false;
				setImgSizeSelector();
				myatCellTable.setVisibleRangeAndClearData(new Range(0, myatPager.getPageSize()), true);
			}
		}


		@Override
		public void onFileUploadSuccess(AssetJso asset) {
			asset.setAttachment(true);
			dataProvider.getList().add(0, asset);
			dataProvider.refresh();
			aatCellTable.redraw();
		}


		@Override
		public void onFileUploadFailure(UploadResponseJso urjso) {
			;
		}
}
